#ifndef HSL_DECISION_MAKER_H
#define HSL_DECISION_MAKER_H

#include "Selected.h"
#include "None.h"

// * The DecisionMaker class needs a variable number of template 
// arguments. This is implemented in a typical way that uses
// partial template specialization. For a simple example
// of this technique, see http://goo.gl/F3Zw7
// 
// FUTURE (C++0x): Can use variadic templates for a simpler 
// implementation.
//
// 
// * The DecisionMaker class returns (possibly large) collections by value. 
// Almost all compilers now implement "Return Value Optimization" at default
// (and higher) optimization levels. See, for example, http://goo.gl/dWAXD

template <typename T, template<class> class S, typename F1 = None, 
          typename F2 = None, typename F3 = None>
class DecisionMaker;

/// DecisionMaker makes the selection of some out of multiple choices at a Choice Point.
/// 
/// T --  is the type of an output (Target).
/// S --  is the type of a container for the Selected outputs.
template <class T, template<class> class S>
class DecisionMaker<T, S>
{
    public:
        /// Public function used to ask DecisionMaker to make a selection. 
        /// 
        /// OUT: $S<T>$ -- the list of output candidates
        S<T> select(); 
};

/// DecisionMaker makes the selection of some out of multiple choices at a Choice Point.
/// 
/// T --  is the type of an output (Target).
/// S --  is the type of a container for the Selected outputs.
/// F1 -- is the type of a feature used to make a selection
template <class T, template<class> class S, class F1>
class DecisionMaker<T, S, F1>
{
    public:

        /// Public function used to ask DecisionMaker to make a selection. 
        /// 
        /// OUT: $S<T>$ -- the list of output candidates
        /// IN:  $feature1$  -- the input needed for making the selection. 
        S<T> select(const F1& feature1) const; 
};

/// DecisionMaker makes the selection of some out of multiple choices at a Choice Point.
/// 
/// T --  is the type of an output (Target).
/// S --  is the type of a container for the Selected outputs.
/// F1 -- is the type of a feature used to make a selection
template <class T, template<class> class S, class F1, class F2>
class DecisionMaker<T, S, F1, F2>
{
    public:

        /// Public function used to ask DecisionMaker to make a selection. 
        /// 
        /// OUT: $S<T>$ -- the list of output candidates
        /// IN:  $feature1$  -- an input needed for making the selection. 
        /// IN:  $feature2$  -- an input needed for making the selection. 
        S<T> select(const F1& feature1, const F2& feature2) const; 
};

#endif //HSL_DECISION_MAKER_H
